var Uploader = (function () {
    function Uploader(opt) {
        this.colWidth = [40, 150, 70, 100, 150, 70, 40];
        this.arrStatus = ["未上传", "上传中", "已暂停", "已上传", "失败"];
        this.arrFiles = [];
        var defOpt = {
            el: "", url: "", tmplPath: "/scripts/uploader.html",
            data: null, filter: null
        };
        for (var o in defOpt) {
            this[o] = opt[o] ? opt[o] : defOpt[o];
        }
        this.init();
    }
    Uploader.prototype.init = function () {
        var _this = this;
        if (typeof this.el === "string")
            this.el = document.querySelector(this.el);
        if (!this.el || !this.url) {
            alert("参数不正确！");
            return;
        }
        this.el.innerHTML =
            "<div class=\"up-wrapper\">\n    <div class=\"up-tools\">\n        <div class=\"up-add\">\n            <button class=\"up-button\">\u6DFB\u52A0\u6587\u4EF6</button>\n            <input type=\"file\" class=\"up-file\" multiple>\n        </div>\n        <button class=\"up-button\">\u4E0A\u4F20</button>\n        <button class=\"up-button\">\u505C\u6B62\u4E0A\u4F20</button>\n        <button class=\"up-button\">\u5220\u9664\u6240\u6709</button>\n    </div>\n    <div>\n        <table class=\"up-table\">\n            <colgroup>\n                <col>\n                <col>\n                <col>\n                <col>\n                <col>\n                <col>\n                <col>\n            </colgroup>\n            <thead>\n                <tr>\n                    <th>\u5E8F\u53F7</th>\n                    <th>\u6587\u4EF6\u540D</th>\n                    <th>\u7C7B\u578B</th>\n                    <th>\u5927\u5C0F</th>\n                    <th>\u8FDB\u5EA6</th>\n                    <th>\u72B6\u6001</th>\n                    <th>\u64CD\u4F5C</th>\n                </tr>\n            </thead>\n            <tbody>\n            </tbody>\n        </table>\n    </div>\n</div>";
        Array.prototype.slice.call(this.el.querySelectorAll("col")).forEach(function (col, idx) {
            col.style.width = _this.colWidth[idx] + "px";
        });
        this.$file = this.el.querySelector(".up-file");
        this.$tbody = this.el.querySelector("tbody");
        this.$btnUpload = this.$file.parentElement.nextElementSibling;
        this.$btnCancel = this.$btnUpload.nextElementSibling;
        this.$btnDelAll = this.$btnCancel.nextElementSibling;
        this.bindEvent();
    };
    Uploader.prototype.bindEvent = function () {
        this.$file.addEventListener("change", this.addAll.bind(this), false);
        this.$btnUpload.addEventListener("click", this.uploadAll.bind(this), false);
        this.$btnCancel.addEventListener("click", this.abortAll.bind(this), false);
        this.$btnDelAll.addEventListener("click", this.delAll.bind(this), false);
        this.$tbody.addEventListener("click", this.delOneFile.bind(this), false);
        this.el.addEventListener("dragenter", this.dragEnter.bind(this), false);
        this.el.addEventListener("dragover", this.dragOver.bind(this), false);
        this.el.addEventListener("dragleave", this.dragLeave.bind(this), false);
        this.el.addEventListener("drop", this.dragDrop.bind(this), false);
    };
    Uploader.prototype.addAll = function () {
        this.addFileListToQueue(this.$file.files);
    };
    Uploader.prototype.uploadAll = function () {
        var _this = this;
        this.arrFiles.forEach(function (fs) {
            if (fs.status == 0 || fs.status == 2) {
                _this.upload(fs);
                _this.setRowStatebyfs(fs, 1);
            }
        });
    };
    Uploader.prototype.abortAll = function () {
        var _this = this;
        this.arrFiles.forEach(function (fs) {
            if (fs.status == 1) {
                fs.request.abort();
                _this.setRowStatebyfs(fs, 2);
            }
        });
    };
    Uploader.prototype.delAll = function () {
        this.abortAll();
        this.arrFiles.length = 0;
        this.$tbody.innerHTML = '';
    };
    Uploader.prototype.delOneFile = function (ev) {
        var tar = ev.target;
        if (tar.classList.contains("up-file-del")) {
            var tr = tar.parentElement.parentElement, idx = tr.rowIndex - 1;
            this.arrFiles.splice(idx, 1);
            tr.remove();
            this.resetNo();
        }
    };
    Uploader.prototype.dragEnter = function (e) {
        console.log("enter");
        e.preventDefault();
        if (e.currentTarget == this.el)
            this.el.classList.add("up-drag");
    };
    Uploader.prototype.dragOver = function (e) {
        console.log("over");
        e.preventDefault();
        clearTimeout(this._leaveTimer);
    };
    Uploader.prototype.dragLeave = function (e) {
        var _this = this;
        console.log("leave");
        e.preventDefault();
        clearTimeout(this._leaveTimer);
        this._leaveTimer = setTimeout(function () {
            return _this.el.classList.remove("up-drag");
        }, 100);
    };
    Uploader.prototype.dragDrop = function (e) {
        console.log("drop");
        e.preventDefault();
        this.addFileListToQueue(e.dataTransfer.files);
        this.el.classList.remove("up-drag");
    };
    Uploader.prototype.addOnSuccess = function (fs) {
        this.setRowStatebyfs(fs, 3);
    };
    Uploader.prototype.addOnError = function (fs) {
        this.setRowStatebyfs(fs, 4);
    };
    Uploader.prototype.addOnPregress = function (fs, e) {
        var per = Math.min(Math.round((e.loaded / e.total) * 100), 100) + "%";
        var row = this.findRowbyfs(fs);
        if (row) {
            var bar = row.querySelector(".up-pg-bar");
            bar.style.background = "linear-gradient(to right, #5cb85c " + per + ",#fff 0)";
            bar.nextElementSibling.textContent = per;
        }
    };
    Uploader.prototype.checkFile = function (filename) {
        return !this.filter || new RegExp(this.filter.map(function (f) { return "(" + f + ")$"; }).join('|')).test(filename);
    };
    Uploader.prototype.getExt = function (file) {
        var pos = file.name.lastIndexOf(".");
        return pos >= 0 ? file.name.substr(pos) : "未知";
    };
    Uploader.prototype.humanize = function (size) {
        var units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
        var ord = Math.floor(Math.log(size) / Math.log(1024));
        ord = Math.min(Math.max(0, ord), units.length - 1);
        var s = Math.round((size / Math.pow(1024, ord)) * 100) / 100;
        return s + ' ' + units[ord];
    };
    Uploader.prototype.findRowbyfs = function (fs) {
        var pos = this.arrFiles.indexOf(fs);
        return pos >= 0 ? this.$tbody.querySelectorAll("tr").item(pos) : null;
    };
    Uploader.prototype.setRowStatebyfs = function (fs, status) {
        fs.status = status;
        var row = this.findRowbyfs(fs);
        if (row) {
            row.children[5].textContent = this.arrStatus[status];
        }
    };
    Uploader.prototype.resetNo = function () {
        var children = this.$tbody.children, cnt = children.length;
        for (var i = 0; i < cnt; i++)
            children[i].children[0].textContent = (i + 1);
    };
    Uploader.prototype.upload = function (fs) {
        var _this = this;
        fs.request = new XMLHttpRequest();
        fs.request.open("post", this.url);
        fs.request.upload.onprogress = function (e) { return _this.addOnPregress(fs, e); };
        fs.request.onload = function () {
            if (fs.request.status >= 200 && fs.request.status < 400)
                _this.addOnSuccess(fs);
            else
                _this.addOnError(fs);
        };
        fs.request.onerror = function () { return _this.addOnError(fs); };
        var fd = new FormData();
        fd.append("files", fs.file);
        if (this.data) {
            for (var k in this.data)
                fd.append(k, this.data[k]);
        }
        fs.request.send(fd);
    };
    Uploader.prototype.addFileListToQueue = function (filelist) {
        var _this = this;
        var files = Array.prototype.slice.call(filelist);
        if (!files.length)
            return;
        files.forEach(function (f) {
            _this.checkFile(f.name) && _this.addFileToQueue(f);
        });
    };
    Uploader.prototype.addFileToQueue = function (file) {
        var found = false;
        this.arrFiles.forEach(function (fs) {
            if (fs.file.name == file.name && fs.file.size == file.size)
                found = true;
        });
        if (!found) {
            this.$tbody.insertAdjacentHTML("beforeend", "<tr>\n    <td>" + (this.arrFiles.length + 1) + "</td>\n    <td>" + file.name + "</td>\n    <td>" + this.getExt(file) + "</td>\n    <td>" + this.humanize(file.size) + "</td>\n    <td><div class=\"up-pg\">\n            <div class=\"up-pg-bar\"></div>\n            <div class=\"up-pg-value\"></div>\n        </div>\n    </td>\n    <td class=\"up-center\">" + "未上传" + "</td>\n    <td class=\"up-center\">\n        <a href=\"#\" class=\"up-file-del\">" + "删除" + "</a>\n    </td>\n</tr>");
            this.arrFiles.push({ file: file, status: 0 });
        }
    };
    return Uploader;
}());
